﻿using FrameWork.Log;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyServer.Common
{
    /// <summary>
    /// 表示数据交换中心基类
    /// </summary>
    public abstract class DataCenterBase : LogableClassBase
    {

        #region========私有变量========
         
        #endregion

        #region==========属性==========

        /// <summary>
        /// 表示数据中心装载的数据读取器
        /// </summary>
        public DataReaderBase Reader { get; protected set; }
        /// <summary>
        /// 表示数据中心装载的数据发送器
        /// </summary>
        public DataSenderBase Sender { get; protected set; }
        /// <summary>
        /// 表示数据中心装载的数据操作器
        /// </summary>
        public DataOperatorBase Operator { get; protected set; }
        /// <summary>
        /// 表示连接监听管理器实例
        /// </summary>
        public ConnectManagerBase ConnectionManager { get; protected set; }
        /// <summary>
        /// 表示数据中心装载的数据侦听器
        /// </summary>
        public DataListenerBase Listener { get; protected set; }
        /// <summary>
        /// 表示数据中心装载的数据压缩器
        /// </summary>
        public DataCompressorBase Compressor { get; protected set; }

        #endregion

        #region=======可重写方法=======

        private object lock1 = new object();
        protected virtual void ConnectionManager_NewConnectionJoin(object sender, ConnectEventArgs e)
        {
            lock (lock1)
            {
                PrintLog(LogType.Info, "新连接加入，正在加入侦听队列...", e.Connect);
                Listener.AddConnect(e.Connect);
                e.Canceled = false;
            }
        }
        private object lock2 = new object();
        protected virtual void DataListener_DataAvailable(object sender, DataListenerEventArgs e)
        {
            lock (lock2)
            {
                Reader.AddToQueue(e.Data);
                e.IsCancel = false;
            }
        }
        private object lock3 = new object();
        protected virtual void Operator_AfterOperateData(object sender, DataAfterOperateEventArgs e)
        {
            lock (lock3)
            {
                if (e.Result==OperateResult.Success)
                {
                    DataPackageCollection col = e.ResultData;
                    if (col != null)
                    {
                        PrintLog(LogType.Info, "正在回复操作结果...");
                        Sender.AddToQueue(col);
                    }
                }
            }
        }

        private object lock4 = new object();
        protected virtual void Reader_AfterOperateData(object sender, DataAfterOperateEventArgs e)
        {
            lock (lock4)
            {
                if (e.Result==OperateResult.Success)
                {
                    DataPackageCollection col = e.OperateData;
                    if (col.OperatedPkgCount == col.Count)
                    {
                        if (col.Count == 0 && col.DataCount==0)
                        {
                            col.State = PackageCollectionState.Created;
                            Reader.AddToQueue(col);
                            return;
                        }
                        Operator.AddToQueue(col);
                        if (Reader.GetTagLeftPacket(col.Tag) != -1)
                        {
                            return;
                        }
                        Listener.AddConnect(col.Tag);
                    }
                }
            }
        }
        protected virtual void Reader_ReadTimeout(object sender, ReadTimeoutEventArgs e)
        {
            PrintLog(LogType.Info, "数据读取已超时...正在重新加入侦听队列...",e.TimeoutPkg);
            if(e.TimeoutPkg.PackageName!="")
                Listener.AddConnect(e.TimeoutPkg.Tag, false);
        }

        #endregion

        #region========公共方法========

        /// <summary>
        /// 开启数据交换中心
        /// </summary>
        /// <returns></returns>
        public virtual bool Start()
        {
            PrintLog(LogType.Info, "正在启动数据收发中心...");
            PrintLog(LogType.Info, "正在启动读取器...");
            Reader.Start();
            Reader.AfterOperateData += Reader_AfterOperateData;
            Reader.ReadTimeout += Reader_ReadTimeout;
            PrintLog(LogType.Info, "正在启动发送器...");
            Sender.Start();
            PrintLog(LogType.Info, "正在启动处理器...");
            Operator.Start();
            Operator.AfterOperateData += Operator_AfterOperateData;
            PrintLog(LogType.Info, "正在启动连接管理器...");
            ConnectionManager.StartListen();
            ConnectionManager.NewConnectionJoin += ConnectionManager_NewConnectionJoin;
            PrintLog(LogType.Info, "正在启动侦听器...");
            Listener.Start();
            Listener.DataAvailable += DataListener_DataAvailable;
            PrintLog(LogType.Info, "数据中心启动成功！");
            return true;
        }

        /// <summary>
        /// 停止数据交换中心
        /// </summary>
        /// <returns></returns>
        public virtual bool Stop(bool IsClearQueue = true)
        {
            PrintLog(LogType.Info, "正在停止数据收发中心...");
            PrintLog(LogType.Info, "正在停止读取器...");
            Reader.Stop();
            Reader.AfterOperateData -= Reader_AfterOperateData;
            PrintLog(LogType.Info, "正在停止发送器...");
            Sender.Stop();
            PrintLog(LogType.Info, "正在停止操作器...");
            Operator.Stop();
            Operator.AfterOperateData -= Operator_AfterOperateData;
            PrintLog(LogType.Info, "正在停止连接管理器...");
            ConnectionManager.Stop();
            PrintLog(LogType.Info, "正在停止侦听器...");
            Listener.Stop();
            Listener.DataAvailable -= DataListener_DataAvailable;
            if (IsClearQueue)
            {
                PrintLog(LogType.Info, "正在清空队列...");
                Reader.ClearQueue();
                Sender.ClearQueue();
                Operator.ClearQueue();
                Listener.Clear();
                ConnectionManager.ClientList.Clear();
            }
            PrintLog(LogType.Info, "数据中心停止成功！");
            return true;
        }

        #endregion

        #region========构造函数========

        public DataCenterBase(DataCompressorBase Compressor = null)
        {
            this.Compressor = Compressor;
        }

        #endregion
    }
}
